package controller

import (
	"context"
	"errors"
	"time"

	"github.com/gogf/gf/v2/crypto/gmd5"
	"github.com/gogf/gf/v2/encoding/gbase64"
	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/text/gstr"
	"github.com/gogf/gf/v2/util/grand"
	"github.com/tiger1103/gfast/v3/api/v1/wxappapi"
	"github.com/tiger1103/gfast/v3/internal/app/app/dao"
	"github.com/tiger1103/gfast/v3/internal/app/app/model/do"
	"github.com/tiger1103/gfast/v3/internal/app/app/model/entity"
	"github.com/tiger1103/gfast/v3/internal/app/common/service"
)

var UserController = new(userController)

type userController struct{}

func (c *userController) Get(ctx context.Context, req *wxappapi.WxAppApiGetReq) (res *wxappapi.WxAppApiGetRes, err error) {
	r := g.RequestFromCtx(ctx)
	token := r.GetHeader("Authorization")
	token = gstr.Replace(token, "Bearer ", "")
	cacheUserId := service.Cache().Get(r.GetCtx(), "token_"+token)
	if cacheUserId == nil {
		return nil, errors.New("用户信息无效")
	}
	res = new(wxappapi.WxAppApiGetRes)
	res.UserInfo, err = dao.AppUser.Ctx(ctx).Fields("id,username,nickname,gender,age").WherePri(cacheUserId).One()
	return
}

func (c *userController) Register(ctx context.Context, req *wxappapi.WxAppApiRegisterReq) (res *wxappapi.WxAppApiRegisterRes, err error) {
	res = new(wxappapi.WxAppApiRegisterRes)
	salt := grand.S(6)
	isExist, _ := dao.AppUser.Ctx(ctx).Where("username=?", req.Username).Count()
	if isExist > 0 {
		return res, errors.New("注册失败,用户名已存在")
	}
	newPassword := gmd5.MustEncrypt(req.Password + salt)
	_, err = dao.AppUser.Ctx(ctx).Insert(&do.AppUser{
		Username: req.Username,
		Password: newPassword,
		Salt:     salt,
	})
	if err != nil {
		return nil, errors.New("注册失败")
	}
	return
}

func (c *userController) Login(ctx context.Context, req *wxappapi.WxAppApiLoginReq) (res *wxappapi.WxAppApiLoginRes, err error) {
	var userInfo *entity.AppUser
	err = dao.AppUser.Ctx(ctx).Where(g.Map{
		"username": req.Username,
	}).Scan(&userInfo)

	if err != nil || userInfo == nil {
		return nil, errors.New("用户名不存在")
	}

	if userInfo.Password != gmd5.MustEncrypt(req.Password+userInfo.Salt) {
		return nil, errors.New("密码错误")
	}

	res = new(wxappapi.WxAppApiLoginRes)
	res.Token = gbase64.EncodeString(gjson.MustEncodeString(g.Map{
		"id":           userInfo.Id,
		"username":     userInfo.Username,
		"created_at":   userInfo.CreatedAt,
		"current_time": gtime.Now().Format("Y-m-d H:i:s"),
	}))
	service.Cache().Set(ctx, "token_"+res.Token, userInfo.Id, time.Hour*24*30)
	return
}

func (c *userController) Edit(ctx context.Context, req *wxappapi.WxAppApiUserEditReq) (res *wxappapi.WxAppApiUserEditRes, err error) {
	r := g.RequestFromCtx(ctx)
	token := r.GetHeader("Authorization")
	token = gstr.Replace(token, "Bearer ", "")
	cacheUserId := service.Cache().Get(r.GetCtx(), "token_"+token)
	if cacheUserId == nil {
		return nil, errors.New("用户信息无效")
	}
	if cacheUserId.Uint64() <= 0 {
		return nil, errors.New("用户信息无效")
	}
	userDo := &do.AppUser{}
	if req.Nickname != "" {
		userDo.Nickname = req.Nickname
	}
	if req.Password != "" {
		if req.Password != req.Password2 {
			return nil, errors.New("两次密码输入不一致")
		}
		salt := grand.S(6)
		userDo.Password = gmd5.MustEncrypt(req.Password + salt)
	}
	_, err = dao.AppUser.Ctx(ctx).Where("id=?", cacheUserId.Uint64()).Update(userDo)
	return
}
